﻿using System;
using System.Collections.Generic;
using System.Collections;
using NHDao;
using NHDataAccess;

namespace NHBussines
{
    public abstract class GenericController<T,Id> : IGenericController<T,Id>
    {
        private DaoFactory daoFactory = DaoFactory.Instance(NHDao.DaoFactory.DAO_FACTORY);

        public DaoFactory DaoFactory
        {
            set
            {
                daoFactory = value;
            }
            get
            {
                return daoFactory;
            }
        }


        public IGenericDao<T, Id> GenericDao { get; set; }

        public T FindByid(Id id)
        {
            return GenericDao.FindByid(id);
        }

        public IList<T> FindAll()
        {
            return GenericDao.FindAll();
        }

        public IList<T> FindAllOrdered(IList<string> propertyNames)
        {
            return GenericDao.FindAllOrdered(propertyNames);
        }

        public IList<T> FindByExample(T entity)
        {
            return GenericDao.FindByExample(entity);
        }

        public IList<T> FindBydExampleOrdered(T entity, IList<string> propertyNames)
        {
            return GenericDao.FindBydExampleOrdered(entity, propertyNames);
        }

        public IList<T> FindLikeExample(T entity)
        {
            return GenericDao.FindLikeExample(entity);
        }

        public IList<T> FindLikeExampleOrdered(T entity, IList<string> propertyNames)
        {
            return GenericDao.FindBydExampleOrdered(entity, propertyNames);
        }

        public IList<T> FindLikeExampleIgnoreCase(T entity)
        {
            return GenericDao.FindLikeExampleIgnoreCase(entity);
        }

        public IList<T> FindLikeExampleIgnoreCaseOrdered(T entity, IList<string> propertyNames)
        {
            return GenericDao.FindLikeExampleIgnoreCaseOrdered(entity, propertyNames);
        }

        public IList<T> FindByQuery(string query)
        {
            return GenericDao.FindByQuery(query);
        }

        public IList<T> FindByQuery(string query, string[] parameters, object[] values)
        {
            return GenericDao.FindByQuery(query, parameters, values);
        }

        public IList<T> FindByNamedQuery(string query)
        {
            return GenericDao.FindByNamedQuery(query);
        }

        public IList<T> FindByNamedQuery(string query, string[] parameters, object[] values)
        {
            return GenericDao.FindByNamedQuery(query, parameters, values);
        }

        public IList FindObjectsByQuery(string query)
        {
            return GenericDao.FindObjectsByQuery(query);
        }

        public IList FindObjectsByNamedQuery(string query)
        {
            return GenericDao.FindObjectsByNamedQuery(query);
        }

        public IList FindObjectsByNamedQuery(string query, string[] parameteres, object[] values)
        {
            return GenericDao.FindObjectsByNamedQuery(query,parameteres,values);
        }

        public IList FindObjectsBySQLQuery(string query, string[] parameters, object[] values)
        {
            return GenericDao.FindObjectsBySQLQuery(query, parameters, values);
        }

        public T Save(T entity)
        {
            T newEntity;
            try
            {
                NhibernateHelper.BeginTransaction();
                newEntity = GenericDao.Save(entity);
                NhibernateHelper.EndTransaction();
            }
            catch (Exception ex)
            {
                NhibernateHelper.RollBackTransaction();
                throw ex;
            }
            finally
            {
                NhibernateHelper.CloseSession();
            }
            return newEntity;
        }

        public T Update(T entity)
        {
            T newEntity;
            try
            {
                NhibernateHelper.BeginTransaction();
                newEntity = GenericDao.Update(entity);
                NhibernateHelper.EndTransaction();
            }
            catch (Exception ex)
            {
                NhibernateHelper.RollBackTransaction();
                throw ex;
            }
            finally
            {
                NhibernateHelper.CloseSession();
            }
            return newEntity; 
        }

        public void Delete(T entity)
        {
            try
            {
                NhibernateHelper.BeginTransaction();
                GenericDao.MakeTransient(entity);
                NhibernateHelper.EndTransaction();
            }
            catch (Exception ex)
            {
                NhibernateHelper.RollBackTransaction();
                throw ex;
            }
            finally
            {
                NhibernateHelper.CloseSession();
            }
            
        }
        public void DeleteById(Id id)
        {
            try
            {
                NhibernateHelper.BeginTransaction();
                GenericDao.MakeTransient(FindByid(id));
                NhibernateHelper.EndTransaction();
            }
            catch (Exception ex)
            {
                NhibernateHelper.RollBackTransaction();
                throw ex;
            }
            finally
            {
                NhibernateHelper.CloseSession();
            }
        }

        public Id GetMax(string propertyName)
        {
            return GenericDao.GetMax(propertyName);
        }
    }
}